# k近邻算法一般流程

# (1) 收集数据:可以使用任何方法。
# (2) 准备数据:距离计算所需要的数值，最好是结构化的数据格式。
# (3) 分析数据:可以使用任何方法。
# (4) 训练算法:此步骤不适用于k-近邻算法。
# (5) 测试算法:计算错误率。
# (6) 使用算法:首先需要输入样本数据和结构化的输出结果，然后运行k-近邻算法判定输
#  入数据分别属于哪个分类，最后应用对计算出的分类执行后续的处理。

from numpy import *
import operator


def create_data_set():
    group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels


def classify0(inX, dataSet, labels, k):
    # 计算距离
    dataSetSize = dataSet.shape[0]
    # tile（A,reqs）用于重复A  怎么重复根据reqs
    # 矩阵减法对应位置相减
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet
    # **表示乘方
    sqDiffMat = diffMat ** 2

    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances ** 0.5
    sortedDistIndicies = distances.argsort()

    # 选择距离最小的k个点
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1

    # 排序 key表示按照什么参数进行排序    reverse = True 表示倒序排列
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]


def testClassify0():
    group, labels = create_data_set()
    result = classify0([0, 0], group, labels, 3)
    print(result)


datingTestSet2Path = 'datingTestSet2.txt'


def fileMatrix(filename):
    fr = open(filename)
    arrayOLines = fr.readlines()
    numbersOfLines = len(arrayOLines)
    # 创建numbersOfLines * 3 的 元素为0的矩阵
    returnMatrix = zeros((numbersOfLines, 3))
    classLabelVectors = []
    index = 0
    for line in arrayOLines:
        # strip()参数为空时去掉line里面的空格或换行字符
        # str.strip([chars]);为去掉字符串头尾的指定字符 chars
        line = line.strip()
        listFormLine = line.split('\t')
        # 取前三个元素放到returnMatrix的第index个元素中
        returnMatrix[index, :] = listFormLine[0:3]
        # listFormLine[-1]  当index为负数的时候从末尾开始读数据，-1 为倒数第一数据
        classLabelVectors.append(int(listFormLine[-1]))
        index += 1
    return returnMatrix, classLabelVectors


def testFileMatrix():
    print(fileMatrix(datingTestSet2Path))


import matplotlib
import matplotlib.pyplot as plt


def drawScatterPlot():
    # 创建一个图形
    fig = plt.figure()
    # 添加单个子图
    ax = fig.add_subplot(111)
    datingDataMatrix, classLabelVectors = fileMatrix(datingTestSet2Path)
    ax.scatter(datingDataMatrix[:, 0], datingDataMatrix[:, 1],
               15.0 * array(classLabelVectors), 15.0 * array(classLabelVectors))
    plt.show()







